﻿/*
 * Created by SharpDevelop.
 * User: Taylor
 * Date: 26/08/2009
 * Time: 20:09
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Reflection;

namespace Backuperer
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();	
		}
		//Dictionarys for storing the transfer from,to locations
		Dictionary<string, string> folderLoc = new Dictionary<string, string>();
		Dictionary<string, string> transferLoc = new Dictionary<string, string>();
		string allStuffToWrite;
		string stuffToWrite;
		public static string editTransferLoc;
		public static string editFolderLoc;
		public static string editName;
		int numberOfFiles;
		int transferedFiles = 0;
		bool overWriteFiles = false;
		Thread transferStart;
		//Thread fileCheckStart;
		//MainForm transferThread = new MainForm();
		//Function gets called when you click the Add butto
		void addFolderBtnClick(object sender, EventArgs e)
		{
			try
			{
				//Creates the form
				addFolder addFolderForm = new addFolder();
				//Shows the form
				addFolderForm.ShowDialog();
				//Adds the textfields to the dictionarys
				folderLoc.Add(addFolderForm.folderName,addFolderForm.folderLocation);
				transferLoc.Add(addFolderForm.folderName,addFolderForm.transferLocation);
				folders.Items.Add(addFolderForm.folderName);
			}
			catch(Exception error)
			{
				Debug.WriteLine(error.Message);
			}
		}
		
		//Function gets called on exit and when save button is pressed
		void saveFunction()
		{
			if(File.Exists("config.cfg"))
			{
				File.Delete("config.cfg");
				Debug.WriteLine(File.Exists("config.cfg"));
				File.Create("config.cfg").Close();
			}
			allStuffToWrite = "";
			stuffToWrite = "";
			//Loops through all the transfers
			for(int i = 0;i < folders.Items.Count;i++)
			{
				string folderName = folders.Items[i].ToString();
				string folderTransfer = transferLoc[folderName.ToString()];
				string folderLocation = folderLoc[folderName.ToString()];
				stuffToWrite = folderName + ";" + folderLocation + ";" + folderTransfer + ";" + "\n|\n";
				allStuffToWrite += stuffToWrite;
				//foldersName.WriteLine(stuffToWrite);
				//Debug.WriteLine(stuffToWrite);
			}
			string[] allStuffToWriteA = new string[1];
			allStuffToWriteA[0] = allStuffToWrite;
			try
			{
				//Writes them all to a config
				File.WriteAllLines("config.cfg",allStuffToWriteA);
			}
			catch(Exception cake)
			{
				Debug.WriteLine(cake.Message);
			}
		}
		
		//Gets called on form load
		void loadFunction()
		{
			//Creates a new streamReader for reading the config file
			StreamReader foldersName = new StreamReader(File.OpenRead("config.cfg"));
			try
			{
				string input;
				//While there are lines in the file
				while((input = foldersName.ReadLine()) != null)
				{
					string[] dnSplitDelimeters = new string[] {";"};
					//Splits up the line into an array
					string[] dnSplit = input.Split(dnSplitDelimeters, StringSplitOptions.None);
					if(dnSplit.Length != 1)
					{
						//dnSplit[0] = name, dnSplit[1] = transferFrom, dnSplit[2] = transferTo
						transferLoc.Add(dnSplit[0],dnSplit[2]);
						folderLoc.Add(dnSplit[0],dnSplit[1]);
						//Adds the transfer to the listbox
						folders.Items.Add(dnSplit[0]);
					}
				}
			}
			catch(Exception cake2)
			{
				Debug.WriteLine(cake2.Message);
			}
			//Closes off the streamReader
			foldersName.Close();
		}
			
		//Function for transfering folders
		void transferFunction(string rootDirectory,string transferDirectory,string Message)
		{
			//Loops through all directories and calls the function again on the new folders
			foreach( string d in Directory.GetDirectories(rootDirectory))
			{
				//Splits folder location and splices it into the transferlocation to see if it exists
				//If not it creates the folder
				string[] dSplitDelimeters = new string[] {"\\"};
				string[] dSplit = d.Split(dSplitDelimeters, StringSplitOptions.None);
				int dSplitLength = dSplit.Length;
				string dName = dSplit[dSplitLength - 1];
				string dExists = transferDirectory + "\\" +  dName;
				if(!Directory.Exists(dExists))
				{
					Directory.CreateDirectory(dExists);
				}
				//Calls it again 
				transferFunction(d,dExists,"Function");
				//Thread transfer = new Thread(new ThreadStart());
			}
			
			//Transfers all the files inside the directory to the respective directory on the transfer end
			foreach( string f in Directory.GetFiles(rootDirectory))
			{
				Debug.WriteLine(f);
				transferedFiles++;
				numberOfFiles--;
				if(numberOfFiles > -1 && !Disposing)
				{
					try
					{
						transferedLabel.Text = transferedFiles.ToString();
						transferProgress.Value++;
					}
					catch(Exception exc)
					{
						MessageBox.Show(exc.Message);
						System.Diagnostics.Process.GetCurrentProcess().Kill();
					}
				}
				
				string[] fSplitDelimeters = new string[] {"\\"};
				string[] fSplit = f.Split(fSplitDelimeters, StringSplitOptions.None);
				int fSplitLength = fSplit.Length;
				string fName = fSplit[fSplitLength - 1];
				string fileExists = transferDirectory + "\\" +  fName;
				
				if(numberOfFiles == 0)
				{
					programStatusLabel.Text = "Ready";
					numberOfFiles = 0;
					transferedFiles = 0;
					MessageBox.Show("Transfer Done");
					transferProgress.Value = 0;
					transferedLabel.Text = "0";
					totalFilesLabel.Text = "0";
					transferProgress.Value = 0;
				}
				
				//Deletes file if it exists on the other end to stop conflicts
					if(File.Exists(fileExists) && fileExists != "C:\\Users\\Taylor\\Desktop\\Backuperer\\config.cfg")
					{
						try
						{
							if(overWriteFiles == true || overwriteCheck.Checked)
								removeReadOnly(fileExists);
							else
							{
								overwriteCheck overWriteCheckForm = new overwriteCheck();
								overWriteCheckForm.file = fileExists;
								overWriteCheckForm.ShowDialog(); 
								int choice = overWriteCheckForm.choice;
								if(choice == 0)
								{
									removeReadOnly(fileExists);
								}
								else if(choice == 1)
								{
									removeReadOnly(fileExists);
									overWriteFiles = true;
								}
								else
									break;
							}	
							File.Delete(fileExists);
						}
						catch(Exception pp)
						{
							
						}
					}
					if(f != "C:\\Users\\Taylor\\Documents\\SharpDevelop Projects\\Backuperer\\Backuperer\\bin\\Debug\\Backuperer.pdb" && f != "C:\\Users\\Taylor\\Documents\\SharpDevelop Projects\\Backuperer\\Backuperer\\bin\\Debug\\config.cfg")
						File.Copy(f,transferDirectory + "\\" + fName);
			}
		}
		
		void removeReadOnly(string file)
		{
			FileInfo fi = new FileInfo(file);
					
			if((fi.Attributes & FileAttributes.ReadOnly) > 0)
				fi.Attributes -= FileAttributes.ReadOnly;
		}
		
		int getNumFilesDirectory(string directory)
		{
			findNumFilesDirectory(directory);
			return numberOfFiles;
		}
		
		void findNumFilesDirectory(string directory)
		{
			foreach( string d in Directory.GetDirectories(directory))
			{
				findNumFilesDirectory(d);
			}
					
			//Transfers all the files inside the directory to the respective directory on the transfer end
			foreach( string f in Directory.GetFiles(directory))
			{
				numberOfFiles++;
			}
		}
		
		//Gets called when you click the Back-Up Selected button
		void TransferBtnClick(object sender, EventArgs e)
		{
			//If you have a listbox item selected
			if(folders.SelectedIndex != -1)
			{
				programStatusLabel.Text = "Transfering";
				//Gets the transfer from,to locations out of the dictionary using the listbox selected item as the key
				string transferFrom = folderLoc[folders.Items[folders.SelectedIndex].ToString()];
				string transferTo = transferLoc[folders.Items[folders.SelectedIndex].ToString()];
				getNumFilesDirectory(folderLoc[folders.Items[folders.SelectedIndex].ToString()]);
				totalFilesLabel.Text = numberOfFiles.ToString();
				transferedLabel.Text = numberOfFiles.ToString();
				transferProgress.Maximum = numberOfFiles;
				transferProgress.Step = 1;
				
				//Does some funky thread stuff
				ThreadStart transfer = delegate { transferFunction(transferFrom,transferTo,"Button"); };
				transferStart = new Thread(transfer);
				transferStart.Start();
				//Thread transfer = new Thread(new ThreadStart(transferThread.));
				//transfer.Start();
			}
			else
			{
				MessageBox.Show("Please Select A Backup");
			}
		}
		
		//Gets called on start
		void MainFormLoad(object sender, EventArgs e)
		{
			//Makes config if it does not exist
			if(!File.Exists("config.cfg"))
			{
				File.Create("config.cfg").Close();
			}
			//Runs the loadfunction
			loadFunction();
			MainForm.CheckForIllegalCrossThreadCalls = false;
		}
		
		//Runs the saveFunction when the button gets clicked
		void SaveBtnClick(object sender, EventArgs e)
		{
			saveFunction();
		}
		
		//Calls saveFunction on application closing
		void MainFormFormClosing(object sender, FormClosingEventArgs e)
		{
			saveFunction();
			System.Diagnostics.Process.GetCurrentProcess().Kill();
		}
		
		//Removes the currently selected transfer from the application and resaves
		void DeleteBtnClick(object sender, EventArgs e)
		{
			if(folders.SelectedIndex != -1)
			{
				folderLoc.Remove(folders.SelectedIndex.ToString());
				transferLoc.Remove(folders.SelectedIndex.ToString());
				folders.Items.RemoveAt(folders.SelectedIndex);
				saveFunction();
			}
			else
				MessageBox.Show("Please Select A Backup");
		}
		
		void FoldersSelectedIndexChanged(object sender, EventArgs e)
		{
			try
			{
				if(folders.SelectedIndex != -1 && folders.Items[folders.SelectedIndex] != null)
				{
					info.Items.Clear();
					info.Items.Add("Transfer From:");
					info.Items.Add(folderLoc[folders.Items[folders.SelectedIndex].ToString()]);
					info.Items.Add("Transfer To:");
					info.Items.Add(transferLoc[folders.Items[folders.SelectedIndex].ToString()]);
				}
			}
			catch(Exception l)
			{
				
			}
		}
		
		void DuplicateBtnClick(object sender, EventArgs e)
		{
			try
			{
				if(folders.SelectedIndex != -1)
				{
					transferLoc.Add(folders.Items[folders.SelectedIndex].ToString() + " " + "(Copy)",transferLoc[folders.Items[folders.SelectedIndex].ToString()]);
					folderLoc.Add(folders.Items[folders.SelectedIndex].ToString() + " " + "(Copy)",folderLoc[folders.Items[folders.SelectedIndex].ToString()]);
					folders.Items.Add(folders.Items[folders.SelectedIndex].ToString() + " " + "(Copy)");
				}
				else
					MessageBox.Show("Please Select A Backup");
			}
			catch(Exception p)
			{
				
			}
		}
		
		void EditBtnClick(object sender, EventArgs e)
		{
			try
			{
				if(folders.SelectedIndex != -1)
				{
					programStatusLabel.Text = "Editing";
					addFolder editForm = new addFolder();
					editFolderLoc = folderLoc[folders.Items[folders.SelectedIndex].ToString()];
					editTransferLoc = transferLoc[folders.Items[folders.SelectedIndex].ToString()];
					editName = folders.Items[folders.SelectedIndex].ToString();
					editForm.ShowDialog();
					
					string oldName = folders.Items[folders.SelectedIndex].ToString();
					programStatusLabel.Text = "Ready";
					if(editForm.folderName != oldName)
					{
						folderLoc.Remove(oldName);
						transferLoc.Remove(oldName);
						folders.Items.RemoveAt(folders.SelectedIndex);
						folders.Items.Add(editForm.folderName);
						transferLoc.Add(editForm.folderName,editForm.transferLocation);
						folderLoc.Add(editForm.folderName,editForm.folderLocation);
					}
					else
					{
						transferLoc[oldName] = editForm.transferLocation;
						folderLoc[oldName] = editForm.folderLocation;
					}
				}
				else
					MessageBox.Show("Please Select A Backup");
			}
			finally
			{
				
			}
		}
		
		void ReverseTransferClick(object sender, EventArgs e)
		{
			//If you have a listbox item selected
			if(folders.SelectedIndex != -1)
			{
				programStatusLabel.Text = "Transfering";
				//Gets the transfer from,to locations out of the dictionary using the listbox selected item as the key
				string transferFrom = transferLoc[folders.Items[folders.SelectedIndex].ToString()];
				string transferTo = folderLoc[folders.Items[folders.SelectedIndex].ToString()];
				getNumFilesDirectory(transferLoc[folders.Items[folders.SelectedIndex].ToString()]);
				totalFilesLabel.Text = numberOfFiles.ToString();
				transferedLabel.Text = numberOfFiles.ToString();
				transferProgress.Maximum = numberOfFiles;
				transferProgress.Step = 1;
				
				//Does some funky thread stuff
				ThreadStart transfer = delegate { transferFunction(transferFrom,transferTo,"Button"); };
				transferStart = new Thread(transfer);
				transferStart.Start();
				//Thread transfer = new Thread(new ThreadStart(transferThread.));
				//transfer.Start();
			}
			else
			{
				MessageBox.Show("Please Select A Backup");
			}
		}
	}
}
